using Circus.Syntax;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Runtime.CompilerServices;
namespace Circus.CodeEditor.Serialization
{
	public class FmtImport : IDisposable
	{
		protected internal class FormattedItem
		{
			public string Tag;
			public FontStyle FontStyle;
			public FontStyle ExcludeStyle;
			public Color ForeColor;
			public Color BackColor;
			public bool StyleValid;
		}
		private IList<FmtImport.FormattedItem> stack;
		private FontStyle defaultStyle;
		protected CodeEditor edit;
		protected TextReader reader;
		protected ReadFormattedTextEventArgs readFormattedArgs;
	    public event ReadFormattedTextEvent ReadFormattedText;
		public FontStyle DefaultStyle
		{
			get
			{
				return this.defaultStyle;
			}
			set
			{
				this.defaultStyle = value;
			}
		}
		public FmtImport()
		{
			this.stack = new List<FmtImport.FormattedItem>();
			this.readFormattedArgs = new ReadFormattedTextEventArgs();
		}
		~FmtImport()
		{
			this.Dispose(false);
		}
		protected void Pop(string tag)
		{
			for (int i = this.stack.Count - 1; i >= 0; i--)
			{
				FmtImport.FormattedItem formattedItem = this.stack[i];
				if (formattedItem.Tag == tag)
				{
					this.stack.RemoveAt(i);
					break;
				}
			}
		}
		protected void Push(string tag)
		{
			FmtImport.FormattedItem formattedItem = new FmtImport.FormattedItem();
			formattedItem.Tag = tag;
			this.stack.Add(formattedItem);
		}
		protected FmtImport.FormattedItem GetCurrentItem()
		{
			if (this.stack.Count == 0)
			{
				this.stack.Add(new FmtImport.FormattedItem());
			}
			return this.stack[this.stack.Count - 1];
		}
		protected void GetCurrentAttributes(out Color foreColor, out Color backColor, out FontStyle fontStyle)
		{
			foreColor = Color.Empty;
			backColor = Color.Empty;
			fontStyle = this.DefaultStyle;
			foreach (FmtImport.FormattedItem current in this.stack)
			{
				if (current.ForeColor != Color.Empty)
				{
					foreColor = current.ForeColor;
				}
				if (current.BackColor != Color.Empty)
				{
					backColor = current.BackColor;
				}
				if (current.StyleValid)
				{
					fontStyle = ((fontStyle | current.FontStyle) & ~current.ExcludeStyle);
				}
			}
		}
		protected void WriteFontStyle(FontStyle style, bool value)
		{
			FmtImport.FormattedItem currentItem = this.GetCurrentItem();
			currentItem.StyleValid = true;
			if (value)
			{
				currentItem.ExcludeStyle &= ~style;
				currentItem.FontStyle |= style;
			}
			else
			{
				currentItem.FontStyle &= ~style;
				currentItem.ExcludeStyle |= style;
			}
		}
		protected void WriteForeColor(Color foreColor)
		{
			FmtImport.FormattedItem currentItem = this.GetCurrentItem();
			currentItem.ForeColor = foreColor;
		}
		protected void WriteBackColor(Color backColor)
		{
			FmtImport.FormattedItem currentItem = this.GetCurrentItem();
			currentItem.BackColor = backColor;
		}
		protected void WriteString(string s)
		{
			Color foreColor;
			Color backColor;
			FontStyle fontStyle;
			this.GetCurrentAttributes(out foreColor, out backColor, out fontStyle);
			this.OnReadFormattedText(foreColor, backColor, fontStyle, s);
		}
		protected virtual bool ReadHeader()
		{
			return true;
		}
		protected virtual bool ReadContent()
		{
			this.stack.Clear();
			return true;
		}
		protected virtual void OnReadFormattedText(Color foreColor, Color backColor, FontStyle fontStyle, string text)
		{
			if (this.ReadFormattedText != null)
			{
				this.readFormattedArgs.ForeColor = foreColor;
				this.readFormattedArgs.BackColor = backColor;
				this.readFormattedArgs.FontStyle = fontStyle;
				this.readFormattedArgs.Text = text;
				this.ReadFormattedText(this, this.readFormattedArgs);
			}
		}
		public virtual void BeginRead(TextReader reader, object userData)
		{
			this.reader = reader;
			this.edit = (userData as CodeEditor);
			this.readFormattedArgs.UserData = userData;
		}
		public virtual bool Read()
		{
			return this.ReadHeader() && this.ReadContent();
		}
		public virtual void EndRead()
		{
		}
		protected virtual void Dispose(bool disposing)
		{
		}
		public void Dispose()
		{
			this.Dispose(true);
			GC.SuppressFinalize(this);
		}
	}
}
